<script setup lang="ts" name="VueCodemirror">
import { EditorView, keymap } from '@codemirror/view'
import { EditorState } from '@codemirror/state'
import { basicSetup } from 'codemirror'
import { oneDarkTheme } from '@codemirror/theme-one-dark'
import { standardKeymap, insertTab } from '@codemirror/commands'
import { json } from '@codemirror/lang-json'
import { xml } from '@codemirror/lang-xml'

const langConfigMap = {
  JSON: json(),
  XML: xml()
}

const props = defineProps({
  lang: {
    type: String,
    default: null
  },
  doc: {
    type: String,
    default: ''
  },
  editable: {
    type: Boolean,
    default: false
  }
})

const { lang, doc, editable } = toRefs(props)

const codemirrorRef = ref(null)
const editorView = ref(null)

const initCodemirror = () => {
  if (editorView.value) {
    editorView.value.destroy()
    editorView.value = null
  }
  const state = EditorState.create({
    extensions: [
      basicSetup,
      keymap.of([
        ...standardKeymap,
        {
          key: 'Tab',
          run: insertTab
        }
      ]),
      EditorView.editable.of(editable.value),
      langConfigMap[lang.value]
    ],
    // 编辑器中的内容
    doc: doc.value
  })
  editorView.value = new EditorView({
    state,
    parent: codemirrorRef.value
  })
}

onMounted(() => {
  initCodemirror()
})
</script>

<template>
  <div ref="codemirrorRef" class="codemirror"></div>
</template>

<style scoped lang="scss">
.codemirror{
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
</style>

<style lang="scss">
.cm-editor{
  height: 100%;
}

.cm-scroller{
  font-family: var(--el-font-family)!important;
}

// 代码自动换行
.cm-content{
  flex-shrink: 1!important;
}

.cm-line{
  white-space: pre-wrap;
  word-break: break-word;
  overflow-wrap: anywhere;
}
</style>
